﻿using System;
using System.IO;
using System.ServiceProcess;
using PSE.Hosting.Management.Common;
using PSE.Hosting.ServiceHoster.Configuration;

namespace PSE.Deployment.Util
{
    public static class WcfService
    {
        #region Service Manager

        public static void AddPackage(string serverName, string packageName)
        {
            try
            {
                if (ServiceFactory.Instance.GetService().GetPackageList(serverName).Find(m => m.Name.ToUpper() == packageName.ToUpper()) == null)
                {
                    ServiceFactory.Instance.GetService().AddPackage(serverName, packageName.ToUpper(), String.Empty, String.Empty, String.Empty);

                    ServiceFactory.Instance.GetService().StartPackage(serverName, packageName.ToUpper(), false);
                }
            }
            catch
            {
                try
                {
                    AddPackageInConfigFile(packageName.ToUpper());
                }
                catch
                {
                    throw;
                }
            }
        }

        public static void RemovePackage(string serverName, string packageName)
        {
            try
            {
                if (ServiceFactory.Instance.GetService().GetPackageList(serverName).Find(m => m.Name == packageName.ToUpper()) != null)
                {
                    ServiceFactory.Instance.GetService().RemovePackage(serverName, packageName.ToUpper());
                }
            }
            catch
            {
                try
                {
                    RemovePackageInConfigFile(packageName.ToUpper());
                }
                catch
                {
                    throw;
                }
            }
        }

        public static void AddAssembly(string serverName, string packageName, string file)
        {
            try
            {
                if (ServiceFactory.Instance.GetService().GetAssemblyList(serverName, packageName.ToUpper()).Find(m => m.FileName == Path.GetFileName(file)) == null)
                {
                    ServiceFactory.Instance.GetService().AddAssembly(serverName, packageName.ToUpper(), Path.GetFileName(file), file);

                    ServiceFactory.Instance.GetService().StartAssembly(serverName, packageName.ToUpper(), Path.GetFileName(file));
                }
            }
            catch
            {
                try
                {
                    AddAssemblyInConfigFile(packageName.ToUpper(), file);
                }
                catch
                {
                    throw;
                }
            }
        }

        public static void RemoveAssembly(string serverName, string packageName, string file)
        {
            try
            {
                if (ServiceFactory.Instance.GetService().GetPackageList(serverName).Find(m => m.Name.ToUpper() == packageName.ToUpper()) != null)
                {
                    if (ServiceFactory.Instance.GetService().GetAssemblyList(serverName, packageName.ToUpper()).Find(m => m.FileName == Path.GetFileName(file)) != null)
                    {
                        ServiceFactory.Instance.GetService().RemoveAssembly(serverName, packageName.ToUpper(), Path.GetFileName(file));
                    }
                }
            }
            catch
            {
                try
                {
                    RemoveAssemblyInConfigFile(packageName.ToUpper(), file);
                }
                catch
                {
                    throw;
                }
            }
        }

        public static void StartPackage(string serverName, string packageName)
        {
            try
            {
                if (ServiceFactory.Instance.GetService().GetPackageList(serverName).Find(m => m.Name.ToUpper() == packageName.ToUpper()) != null)
                {
                    ServiceFactory.Instance.GetService().StartPackage(serverName, packageName.ToUpper(), true);
                }
            }
            catch
            {
                try
                {
                    SavePackageStarted(packageName.ToUpper());
                }
                catch
                {
                    throw;
                }
            }
        }

        public static void StopPackage(string serverName, string packageName)
        {
            try
            {
                if (ServiceFactory.Instance.GetService().GetPackageList(serverName).Find(m => m.Name.ToUpper() == packageName.ToUpper()) != null)
                {
                    ServiceFactory.Instance.GetService().StopPackage(serverName, packageName.ToUpper());
                }
            }
            catch
            {
                try
                {
                    SavePackageStoped(packageName.ToUpper());
                }
                catch
                {
                    throw;
                }
            }
        }

        #endregion

        #region Configuration Manager

        private static void AddPackageInConfigFile(string packageName)
        {
            if (ConfigurationFile.Instance.GetPackages().Find(m => m.Name.ToUpper() == packageName.ToUpper()) == null)
            {
                ConfigurationFile.Instance.AddPackage(packageName.ToUpper(), String.Empty, String.Empty, String.Empty);

                ConfigurationFile.Instance.SavePackageStarted(packageName.ToUpper());
            }
        }

        private static void RemovePackageInConfigFile(string packageName)
        {
            if (ConfigurationFile.Instance.GetPackages().Find(m => m.Name == packageName.ToUpper()) != null)
            {
                ConfigurationFile.Instance.RemovePackage(packageName.ToUpper());
            }
        }

        private static void AddAssemblyInConfigFile(string packageName, string file)
        {
            if (ConfigurationFile.Instance.GetAssemblies(packageName.ToUpper()).Find(m => m.FileName == Path.GetFileName(file)) == null)
            {
                ConfigurationFile.Instance.AddAssembly(packageName.ToUpper(), file);
            }
        }

        private static void RemoveAssemblyInConfigFile(string packageName, string file)
        {
            if (ConfigurationFile.Instance.GetPackages().Find(m => m.Name.ToUpper() == packageName.ToUpper()) != null)
            {
                if (ConfigurationFile.Instance.GetAssemblies(packageName.ToUpper()).Find(m => m.FileName == Path.GetFileName(file)) != null)
                {
                    ConfigurationFile.Instance.RemoveAssembly(packageName.ToUpper(), Path.GetFileName(file));
                }
            }
        }

        public static void SavePackageStarted(string packageName)
        {
            if (ConfigurationFile.Instance.GetPackages().Find(m => m.Name.ToUpper() == packageName.ToUpper()) != null)
            {
                ConfigurationFile.Instance.SavePackageStarted(packageName.ToUpper());
            }
        }

        public static void SavePackageStoped(string packageName)
        {
            if (ConfigurationFile.Instance.GetPackages().Find(m => m.Name.ToUpper() == packageName.ToUpper()) != null)
            {
                ConfigurationFile.Instance.SavePackageStoped(packageName.ToUpper());
            }
        }

        #endregion
    }
}
